/**
 * 文件名称 : MultiTouchHandler.java
 * <p>
 * 作者信息 : maidou
 * <p>
 * 创建时间 : 2012-11-1, 下午10:58:24
 * <p>
 * 版权声明 : Copyright (c) 2009-2012 CIeNET Ltd. All rights reserved
 * <p>
 * 评审记录 :
 * <p>
 */

package com.ttomato.game.framework.impl;

import java.util.ArrayList;
import java.util.List;

import android.view.MotionEvent;
import android.view.View;

import com.ttomato.game.framework.Input.TouchEvent;
import com.ttomato.game.framework.Pool;
import com.ttomato.game.framework.Pool.PoolObjectFactory;

/**
 * 请在这里增加文件描述
 * <p>
 */
public class MultiTouchHandler implements TouchHandler
{
    boolean[] mIsTouched = new boolean[20];
    
    int[] mTouchX = new int[20];
    
    int[] mTouchY = new int[20];
    
    Pool<TouchEvent> mTouchPool;
    
    List<TouchEvent> mTouchEvents = new ArrayList<TouchEvent>();
    
    List<TouchEvent> mTouchEventsBuffer = new ArrayList<TouchEvent>();
    
    float mScaleX;
    
    float mScaleY;
    
    public MultiTouchHandler(View view, float scaleX, float scaleY)
    {
        PoolObjectFactory<TouchEvent> factory = new PoolObjectFactory<TouchEvent>()
        {
            
            @Override
            public TouchEvent createObject()
            {
                // TODO Auto-generated method stub
                return new TouchEvent();
            }
        };
        
        mTouchPool = new Pool<TouchEvent>(factory, 100);
        view.setOnTouchListener(this);
        
        mScaleX = scaleX;
        mScaleY = scaleY;
    }
    
    @Override
    public boolean onTouch(View v, MotionEvent event)
    {
        synchronized (this)
        {
            int action = event.getAction() & MotionEvent.ACTION_MASK;
            int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
            int pointerId = event.getPointerId(pointerIndex);
            
            TouchEvent touchEvent;
            
            switch (action)
            {
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_POINTER_DOWN:
                    touchEvent = mTouchPool.newObject();
                    touchEvent.type = TouchEvent.TOUCH_DOWN;
                    touchEvent.pointer = pointerId;
                    touchEvent.x = mTouchX[pointerId] = (int) (event.getX(pointerIndex) * mScaleX);
                    touchEvent.y = mTouchY[pointerId] = (int) (event.getY(pointerIndex) * mScaleY);
                    mIsTouched[pointerId] = true;
                    mTouchEventsBuffer.add(touchEvent);
                    break;
                
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_POINTER_UP:
                case MotionEvent.ACTION_CANCEL:
                    touchEvent = mTouchPool.newObject();
                    touchEvent.type = TouchEvent.TOUCH_UP;
                    touchEvent.pointer = pointerId;
                    touchEvent.x = mTouchX[pointerId] = (int) (event.getX(pointerIndex) * mScaleX);
                    touchEvent.y = mTouchY[pointerId] = (int) (event.getY(pointerIndex) * mScaleY);
                    mIsTouched[pointerId] = false;
                    mTouchEventsBuffer.add(touchEvent);
                    break;
                
                case MotionEvent.ACTION_MOVE:
                    int pointerCount = event.getPointerCount();
                    for (int i = 0; i < pointerCount; i++)
                    {
                        pointerIndex = i;
                        pointerId = event.getPointerId(pointerIndex);
                        
                        touchEvent = mTouchPool.newObject();
                        touchEvent.type = TouchEvent.TOUCH_DRAGGED;
                        touchEvent.pointer = pointerId;
                        touchEvent.x = mTouchX[pointerId] = (int) (event.getX(pointerIndex) * mScaleX);
                        touchEvent.y = mTouchY[pointerId] = (int) (event.getY(pointerIndex) * mScaleY);
                        mTouchEventsBuffer.add(touchEvent);
                    }
                default:
                    break;
            }
            return true;
        }
    }
    
    @Override
    public boolean isTouchDown(int pointer)
    {
        synchronized (this)
        {
            if (pointer < 0 || pointer > 20)
            {
                return false;
            }
            else
            {
                return mIsTouched[pointer];
            }
        }
    }
    
    @Override
    public int getTouchX(int pointer)
    {
        synchronized (this)
        {
            if (pointer < 0 || pointer > 20)
            {
                return 0;
            }
            else
            {
                return mTouchX[pointer];
            }
        }
    }
    
    @Override
    public int getTouchY(int pointer)
    {
        synchronized (this)
        {
            if (pointer < 0 || pointer > 20)
            {
                return 0;
            }
            else
            {
                return mTouchY[pointer];
            }
        }
    }
    
    @Override
    public List<TouchEvent> getTouchEvents()
    {
        synchronized (this)
        {
            int len = mTouchEvents.size();
            for (int i = 0; i < len; i++)
            {
                mTouchPool.free(mTouchEvents.get(i));
            }
            
            mTouchEvents.clear();
            mTouchEvents.addAll(mTouchEventsBuffer);
            mTouchEventsBuffer.clear();
            return mTouchEvents;
        }
    }
    
}
